﻿using App_1.Contracts;
using App_1.Data;
using App_1.Data.Repositoriescs;
using App_1.Identity;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;

namespace App_1.Extensions
{
    public static class ServiceExtensions
    {
        //跨域配置
        public static void ConfigureCors(this IServiceCollection services)
        {
            services.AddCors(options =>
            {
                //options.AddPolicy("AnyPolicy",
                //    builder => builder.AllowAnyOrigin()
                //        .AllowAnyMethod()
                //        .AllowAnyHeader());

                options.AddDefaultPolicy(builder => builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader());
            });
        }

        public static void ConfigureSqlServerContext(this IServiceCollection services, IConfiguration config)
        {
            var connectionString = config.GetConnectionString("GameDb");
            services.AddDbContext<GameManagementDbContext>(
                builder => builder.UseSqlServer(connectionString));
        }

        public static void ConfigureRepositoryWrapper(this IServiceCollection services)
        {
            services.AddScoped<IRepositoryWrapper, RepositoryWrapper>();
        }

        //配置Identity
        public static void ConfigureIdentity(this IServiceCollection services)
        {
            services.AddIdentityCore<IdentityUser>(options =>
            {
                options.Password.RequiredLength = 6;
                options.Password.RequireDigit = false;
                options.Password.RequireUppercase = false;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireLowercase = false;
            }).AddEntityFrameworkStores<GameManagementDbContext>();

            services.AddSingleton<IIdentityService, IdentityService>();
        }

        //配置授权认证
        public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration configuration)
        {
            var jwtSettings = configuration.GetRequiredSection("JwtSettings").Get<JwtSettings>();

            if (jwtSettings is null) throw new NullReferenceException(nameof(JwtSettings));

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)//配置JwtBearer认证方案
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ClockSkew = TimeSpan.Zero,//时钟偏移
                        ValidateIssuer = true,//验证发现者
                        ValidateAudience = true,//验证受众
                        ValidateLifetime = true,//验证有效期
                        ValidateIssuerSigningKey = true,//验证签名
                        ValidIssuer = jwtSettings.Issuer,//确认验证的值
                        ValidAudience = jwtSettings.Audience,
                        IssuerSigningKey = new SymmetricSecurityKey(//生成签名
                            Encoding.UTF8.GetBytes(jwtSettings.Secret)
                        )
                    };
                });
        }


        //配置swagger安全定义
        public static void ConfigureSwagger(this IServiceCollection services)
        {
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen(option =>
            {
                //定义 安全定义方案
                option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Name = "JWT Bearer 认证",
                    In = ParameterLocation.Header,//令牌在请求中的位置
                    Type = SecuritySchemeType.Http,//请求的协议
                    Scheme = "Bearer",//使用的方案
                    BearerFormat = "JWT"//格式
                });

                //添加安全性需求
                option.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        //openapi安全结构
                        new OpenApiSecurityScheme//
                        {
                            Reference = new OpenApiReference
                            {
                                Id = "Bearer",//对象引用了之前定义的 "Bearer" 安全定义方案。
                                Type = ReferenceType.SecurityScheme
                            }
                        },

                        //表示所有的API端点都可以使用这个安全定义方案
                        Array.Empty<string>()
                    }
                });
            });
        }
    }
}